package posts

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/utils/pointy"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"
	"mall/service/blog/rpc/blogclient"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/internal/utils/errorhandler"
	"mall/service/forum/rpc/types/forum"

	"github.com/sirupsen/logrus"
	"github.com/volatiletech/null/v8"
	"github.com/zeromicro/go-zero/core/logx"
)

type BackendBatchUpdatePostsLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendBatchUpdatePostsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendBatchUpdatePostsLogic {
	return &BackendBatchUpdatePostsLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendBatchUpdatePostsLogic) BackendBatchUpdatePosts(in *forum.BackendPostsListReq) (*forum.BackendPostsListResp, error) {
	if in.Ids == nil || len(in.Ids) == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	filterMap := make(map[string]map[string][]any)
	vals := make([]any, 0)
	for _, v := range in.Ids {
		vals = append(vals, v)
	}

	filterMap[model.ForumPostColumns.PostID] = map[string][]any{
		"in": vals,
	}
	var status int32
	var noticeType int32
	var restricted bool // 数据有效
	var recRating bool
	if in.Type != nil {
		switch int32(*in.Type) {
		case globalkey.ForumModTypeReview, globalkey.ForumModTypePhoto: // 审核香评、图片
			if in.Status != nil {
				switch int32(*in.Status) {
				case globalkey.StatusApproved: // 审核通过
					filterMap[model.ForumPostColumns.PostStatus] = map[string][]any{
						"in": {globalkey.StatusPending, globalkey.StatusCheckSuccess},
					}
					status = globalkey.StatusApproved
					noticeType = globalkey.ForumNoticeTypeApproved // 审核通过
					restricted = true
					if int32(*in.Type) == globalkey.ForumModTypeReview {
						recRating = true
					}
				case globalkey.StatusRejected: // 审核驳回
					filterMap[model.ForumPostColumns.PostStatus] = map[string][]any{
						"in": {globalkey.StatusPending, globalkey.StatusCheckSuccess, globalkey.StatusCheckFailed},
					}
					status = globalkey.StatusRejected
					noticeType = globalkey.ForumNoticeTypeRejected // 审核驳回
					restricted = true
				}
			}
		}
	}

	resp := &forum.BackendPostsListResp{}

	if !restricted {
		return resp, nil
	}

	res, _, err := l.svcCtx.Post.GetList(l.ctx, model.M{}, -1, filterMap)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	if len(res) == 0 {
		return resp, nil
	}

	idPostMap := make(map[uint64]*model.ForumPost)
	idParentMap := make(map[uint64]uint64)
	idParentCountMap := make(map[uint64]uint64) //每个百科之下要新增多少 _review_count
	idAuthorMap := make(map[uint64]uint64)
	idCountMap := make(map[uint64]uint)
	titleMap := make(map[uint64]string)
	postMap := make(map[uint64]*forum.ReviewSubscribeInfo)
	var pids []uint64 // post ids
	var ids []any     // post ids
	var sids []string //parent ids  百科id
	//收集数据
	for _, v := range res {
		idAuthorMap[v.PostID] = v.PostAuthorID
		idCountMap[v.PostID] = v.PhotoCount
		excerptRune := []rune(v.PostContent)
		postMap[v.PostID] = &forum.ReviewSubscribeInfo{
			PostContent: v.PostContent,
			ParentId:    v.ParentID,
			AuthorId:    v.PostAuthorID,
		}
		if len(excerptRune) > 20 {
			postMap[v.PostID] = &forum.ReviewSubscribeInfo{
				PostContent: string(excerptRune[0:17]) + "...",
			}
		}

		idPostMap[v.PostID] = v
		pids = append(pids, v.PostID)
		ids = append(ids, v.PostID)
		if v.ParentID > 0 { // 百科ID
			sids = append(sids, strconv.FormatInt(int64(v.ParentID), 10))
			idParentMap[v.PostID] = v.ParentID
			idParentCountMap[v.ParentID] += 1
		}
	}

	//从  百科中取title
	if len(sids) > 0 {
		list, err := l.svcCtx.BlogRpc.BookList(l.ctx, &blogclient.BookListReq{
			Preload:  "blogBook:Id,Title",
			EntryIds: strings.Join(sids, ","),
		})
		if err != nil {
			logrus.Info(fmt.Sprintf("BackendBatchUpdatePost BlogRpc.BookList err: %+v", err))
			return nil, err
		}

		if len(list.Data) > 0 {
			for _, v := range list.Data {
				titleRune := []rune(v.Title)
				if len(titleRune) > 20 {
					titleMap[uint64(v.Id)] = string(titleRune[0:17]) + "..."
				} else {
					titleMap[uint64(v.Id)] = v.Title
				}
			}
		}
	}
	tx, err := l.svcCtx.DB.BeginTx(l.ctx, nil)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	now := time.Now() // 本地时间
	gmtNow := modelx.GetGmtTime(now)
	// 香评修改香评状态
	err = l.svcCtx.Post.UpdateBatch(l.ctx, tx, pids, model.M{
		model.ForumPostColumns.PostStatus:       uint8(status),
		model.ForumPostColumns.PostModifiedDate: now,
		model.ForumPostColumns.PostModifiedGMT:  gmtNow,
	}, &model.ForumPostRel{})
	if err != nil {
		tx.Rollback()
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	if recRating { // 香评审核通过
		//添加统计数据  收藏量  点赞量
		var postMeta []*model.ForumPostMetum
		for _, postID := range pids {
			postMeta = append(postMeta,
				&model.ForumPostMetum{
					PostID:    postID,
					MetaKey:   strings.TrimSpace("_upvote_count"),
					MetaValue: null.StringFrom(strings.TrimSpace("0")),
				},
				&model.ForumPostMetum{
					PostID:    postID,
					MetaKey:   strings.TrimSpace("_collect_count"),
					MetaValue: null.StringFrom(strings.TrimSpace("0")),
				},
				&model.ForumPostMetum{
					PostID:    postID,
					MetaKey:   strings.TrimSpace("_review_count"),
					MetaValue: null.StringFrom(strings.TrimSpace("0")),
				},
			)
		}
		err = l.svcCtx.Post.InsertMeta(l.ctx, tx, postMeta)
		if err != nil {
			tx.Rollback()
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}
		//增加百科下香评量
		var meta []*blogclient.MetaInfo
		for pid, reviewCount := range idParentCountMap {
			if reviewCount > 0 {
				meta = append(meta, &blogclient.MetaInfo{
					Id:    pointy.GetPointer(pid),
					Key:   pointy.GetPointer("_review_count"),
					Value: pointy.GetPointer(strconv.FormatInt(int64(reviewCount), 10)),
				})
			}
		}
		if len(meta) > 0 {
			_, err = l.svcCtx.BlogRpc.SetKBPostMeta(l.ctx, &blogclient.SetKBPostMetaReq{
				Meta: meta,
			})
			if err != nil {
				logrus.Info(fmt.Sprintf("BackendBatchUpdatePost BlogRpc.BackendSetKBPostMeta err: %+v", err))
				tx.Rollback()
				return nil, err
			}
		}
		//添加tag下的香量评
		termRelationshipsFilter := make(map[string]map[string][]any)
		termRelationshipsFilter[model.ForumTermRelationshipColumns.ObjectID] = map[string][]any{
			"in": vals,
		}
		termRelationshipsFilter[model.ForumTermRelationshipColumns.ObjectType] = map[string][]any{
			"equalTo": []any{uint16(globalkey.AttachmentLogTypeForumPost)},
		}
		termRelationshipList, _, err := l.svcCtx.ForumTerm.GetRelationshipList(l.ctx, model.M{}, -1, termRelationshipsFilter)
		if err != nil {
			return nil, err
		}
		//每个tag添加几条
		var termIdCountMap = map[uint64]uint64{}
		if len(termRelationshipList) > 0 {
			for _, v := range termRelationshipList {
				if _, ok := termIdCountMap[v.TermID]; ok {
					termIdCountMap[v.TermID] += 1
				} else {
					termIdCountMap[v.TermID] = 1
				}
			}
		}
		//循环添加
		for termId, count := range termIdCountMap {
			l.svcCtx.ForumTerm.IncreaseMeta(l.ctx, []int64{int64(termId)}, "_post_count", int(count))
		}
	}

	tx.Commit()

	return &forum.BackendPostsListResp{
		PostMap:        postMap,
		ParentTitleMap: titleMap,
		Msg:            i18n.UpdateSuccess,
		NoticeType:     uint64(noticeType),
	}, nil
}
